home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_3
/
psm
/
source
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-28
|
36KB
|
1,172 lines
#include "psm.h"
struct List ScreenModeList;
/**
** Definition of main window
**/
enum {
WINTAGS_ID = 1,
PUBLIST_ID,
OWNER_ID,
CLOSE_ID,
JUMPTO_ID,
EXAMINE_ID,
MAKEDEF_ID,
DEFAULT_ID,
DUPSCRN_ID,
MODSCRN_ID,
SHANGHAI_ID,
AUTOPOP_ID,
NEWSCRN_ID,
QUIT_ID,
ABOUT_ID,
};
#define CURSCRN_GID GO_GRPID_A // Gadget group that needs a public screen
// to be selected.
/**
** Almost a menu strip for the main window
**/
struct NewMenu mainmenu[] = {
{ NM_TITLE, "Project", 0 , 0, 0, 0 },
{ NM_ITEM, "About...", "A", 0, 0, (void *)ABOUT_ID },
{ NM_ITEM, "Quit", "Q", 0, 0, (void *)QUIT_ID },
{ NM_END, NULL, 0 , 0, 0, 0 },
};
static ULONG __saveds __interrupt
main_handler(struct GadOutline *go, ULONG command, struct GOIMsg *msg);
static ULONG main_outline[] = {
GO_OUTLINETAGS(0,0),
TAG_END,
GOA_BaseName, (ULONG)&__BaseName[0],
GOA_SetUserHandler, (ULONG)&main_handler,
GOA_SetTransHookData, NULL,
GOA_UserIDCMP, ~0,
GOA_ErrorReportLevel,
(1L<<GOTYPE_FINE) | (1L<<GOTYPE_FINE2)
| (1L<<GOTYPE_NOTE) | (1L<<GOTYPE_NOTE2)
| (1L<<GOTYPE_WARN) | (1L<<GOTYPE_WARN2)
| (1L<<GOTYPE_ALERT) | (1L<<GOTYPE_ALERT2) | (1L<<GOTYPE_ALERT3)
| (1L<<GOTYPE_FAIL) | (1L<<GOTYPE_FAIL2) | (1L<<GOTYPE_FAIL3),
GOA_AllocMenus, (ULONG)&mainmenu[0],
TAG_END,
GO_WINDOWTAGS(0,WINTAGS_ID),
TAG_END,
WA_Title, (ULONG)&__ShortTitle[0],
WA_ScreenTitle, (ULONG)&__LongTitle[0],
WA_PubScreenFallBack, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW |
IDCMP_INTUITICKS | IDCMP_MENUPICK,
WA_Activate, TRUE,
WA_CloseGadget, TRUE,
WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_SizeGadget, TRUE,
WA_SizeBBottom, TRUE,
WA_SimpleRefresh, TRUE,
WA_BackFill, NULL,
TAG_END,
GO_COMMANDTAGS(0,0),
TAG_END,
GOCT_SetHotKey, 0,
TAG_END,
GO_VERTGRP(0,0,1),
GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
TAG_END,
GO_VDRAWGRP(0,0,1),
GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
TAG_END,
GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63),
TAG_END,
GO_GTBOX(LISTVIEW_KIND, 0, PUBLIST_ID, 1,
(ULONG)&"_Public Screens", PLACETEXT_ABOVE|NG_HIGHLABEL),
GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,500,GOT_PercCharH),
GOCT_SizeUser1, GO_TSIZE(GOM_VarSet,200,GOT_PercCharW),
GOCT_CopyUser1ToTag, GTLV_ScrollWidth,
TAG_END,
GTLV_Selected, ~0,
GTLV_Labels, NULL,
GTLV_ShowSelected, NULL,
GTLV_ScrollWidth, 16,
GT_Underscore, '_',
GA_Disabled, FALSE,
TAG_END,
GO_GTBOX(TEXT_KIND, 0, OWNER_ID, 0,
(ULONG)&"Owner: ", PLACETEXT_LEFT|NG_HIGHLABEL),
GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,500,GOT_PercCharW),
GOCT_SizeSpaceBelow, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
TAG_END,
GTTX_Text, (ULONG)&"",
GTTX_Border, TRUE,
GA_Disabled, FALSE,
TAG_END,
GO_VDRAWGRP(0,0,0),
GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
TAG_END,
GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63),
TAG_END,
GO_HORIZGRP(0,0,0), GOCT_EvenDistGroup, TRUE, TAG_END,
GO_GTBOX(BUTTON_KIND, CURSCRN_GID, CLOSE_ID, 0,
(ULONG)&"_Close", PLACETEXT_IN),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_GTBOX(BUTTON_KIND, CURSCRN_GID, JUMPTO_ID, 0,
(ULONG)&"_Jump to", PLACETEXT_IN),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_GTBOX(BUTTON_KIND, CURSCRN_GID, EXAMINE_ID, 0,
(ULONG)&"_Examine", PLACETEXT_IN),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_ENDGRP(),
GO_HORIZGRP(0,0,0),
GOCT_EvenDistGroup, TRUE,
TAG_END,
GO_GTBOX(BUTTON_KIND, CURSCRN_GID, DUPSCRN_ID, 0,
(ULONG)&"_Dup Scrn", PLACETEXT_IN),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_GTBOX(BUTTON_KIND, CURSCRN_GID, MODSCRN_ID, 0,
(ULONG)&"_Mod Scrn", PLACETEXT_IN),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_ENDGRP(),
GO_HORIZGRP(0,0,0), TAG_END,
GO_GTBOX(BUTTON_KIND, CURSCRN_GID, MAKEDEF_ID, 0,
(ULONG)&"De_fault", PLACETEXT_IN),
GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_GTBOX(TEXT_KIND, 0, DEFAULT_ID, 1, NULL, 0),
GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,500,GOT_PercCharW),
GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
TAG_END,
GTTX_Text, (ULONG)&"",
GTTX_Border, TRUE,
GA_Disabled, FALSE,
TAG_END,
GO_ENDGRP(),
GO_ENDGRP(),
GO_ENDGRP(),
GO_HORIZGRP(0,0,0),
GOCT_EvenDistGroup, TRUE,
GOCT_SizeSpaceAbove, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
TAG_END,
GO_GTBOX(CHECKBOX_KIND, 0, SHANGHAI_ID, 0,
(ULONG)&"_Shanghai", PLACETEXT_RIGHT),
TAG_END,
GTCB_Checked, FALSE,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_GTBOX(CHECKBOX_KIND, 0, AUTOPOP_ID, 0,
(ULONG)&"_AutoPop", PLACETEXT_RIGHT),
TAG_END,
GTCB_Checked, FALSE,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_ENDGRP(),
GO_HORIZGRP(0,0,0),
GOCT_EvenDistGroup, TRUE,
TAG_END,
GO_GTBOX(BUTTON_KIND, 0, NEWSCRN_ID, 0,
(ULONG)&"_New Scrn", PLACETEXT_IN),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_GTBOX(BUTTON_KIND, 0, QUIT_ID, 0,
(ULONG)&"_Quit", PLACETEXT_IN),
TAG_END,
GA_Disabled, FALSE,
GT_Underscore, '_',
TAG_END,
GO_ENDGRP(),
GO_ENDGRP(),
GO_ENDOUTLINE()
};
/**
** Handler for main window
**/
#define TEXT_LEN 252
struct main_globals {
struct List pubscrn_list; // List of screens (struct pubscrn_entry)
struct pubscreen_entry *cur_pubscrn; // Currently selected screen
ULONG ticks_since_update; // How long since it's been updated
struct List empty_list; // Unused pubscrn_entry structures.
struct List outline_list; // All opened outlines.
struct Hook bf_hook;
UBYTE defpub_name[TEXT_LEN+4]; // Name of current default pub screen
};
struct pubscreen_entry {
struct Node node; // ln_Name points to &desc[0]
WORD resv0;
UWORD flags; // as per PubScreenNode
WORD visitor_count; // ""
struct Screen *screen; // the actual screen
struct Task *owner; // task which owns the screen
UBYTE *name; // start of actual name in buffer
UBYTE desc[TEXT_LEN+4]; // description - 'x yy zzzzzzz...'
// x = P if private, yy is visitor count,
// zzz... is screen name.
UBYTE owner_name[TEXT_LEN+4]; // name of owner task.
};
static void update_checkbox(struct GadOutline *go,CMDID cmdid,ULONG newval)
{
ULONG oldval;
oldval = GO_GetObjAttr(go,cmdid,0, GTCB_Checked,FALSE);
if( (!oldval && newval) || (oldval && !newval) ) {
GO_SetObjAttrs(go,cmdid,0, GTCB_Checked,newval,TAG_END);
}
}
static BOOL update_publist(struct GadOutline *go)
{
struct main_globals *gl;
struct PubScreenNode *cur_scrn;
struct pubscreen_entry *cur_entry;
BOOL list_changed = FALSE;
UBYTE name_selected[TEXT_LEN+4];
if( !(gl = go->go_UserData) ) return FALSE;
cur_entry = head_node(&gl->pubscrn_list);
name_selected[0] = 0;
for(cur_scrn = head_node(LockPubScreenList());
cur_scrn != NULL;
cur_scrn = next_node(cur_scrn)) {
// Check if node in list and pubscreen nodes match...
if( cur_entry == NULL || cur_entry->flags != cur_scrn->psn_Flags
|| cur_entry->visitor_count != cur_scrn->psn_VisitorCount
|| strcmp(cur_entry->name,cur_scrn->psn_Node.ln_Name) != 0 ) {
// They don't; set changed flag and detach from listview because
// we are going to make changes.
if(list_changed == FALSE) {
GO_SetObjAttrs(go,PUBLIST_ID,0,GTLV_Labels,~0,TAG_END);
list_changed = TRUE;
}
// If this is the currently selected screen, stash its name.
if(cur_entry && gl->cur_pubscrn == cur_entry) {
strcpy(name_selected,gl->cur_pubscrn->name);
gl->cur_pubscrn = NULL;
}
// If failed because no more entries in list, get a new one.
if(cur_entry == NULL) {
cur_entry = (struct pubscreen_entry *)RemHead(&gl->empty_list);
if(cur_entry == NULL)
cur_entry = AllocVec(sizeof(struct pubscreen_entry),MEMF_PUBLIC);
if(cur_entry != NULL)
AddTail(&gl->pubscrn_list,&cur_entry->node);
}
// Fillin this entry.
if(cur_entry) {
cur_entry->flags = cur_scrn->psn_Flags;
cur_entry->visitor_count = cur_scrn->psn_VisitorCount;
cur_entry->screen = cur_scrn->psn_Screen;
cur_entry->owner = cur_scrn->psn_SigTask;
if(CheckScrnTrack(cur_scrn->psn_Screen)) {
cur_entry->desc[0] = '*';
} else {
cur_entry->desc[0] =
((cur_scrn->psn_Flags&PSNF_PRIVATE) ? 'P' : ' ');
}
cur_entry->desc[1] = (cur_scrn->psn_VisitorCount/10)+ '0';
cur_entry->desc[2] = cur_scrn->psn_VisitorCount
- ((cur_entry->desc[1]-'0')*10) + '0';
cur_entry->desc[3] = ' ';
strncpy(&cur_entry->desc[4],cur_scrn->psn_Node.ln_Name,TEXT_LEN);
cur_entry->node.ln_Name =
&cur_entry->desc[0];
cur_entry->name = &cur_entry->desc[4];
if(cur_scrn->psn_SigTask) {
if(cur_scrn->psn_SigTask->tc_Node.ln_Name) {
strncpy(&cur_entry->owner_name[0],
cur_scrn->psn_SigTask->tc_Node.ln_Name,TEXT_LEN);
} else {
strcpy(&cur_entry->owner_name[0],"Unknown.");
}
} else {
strcpy(&cur_entry->owner_name[0],"None.");
}
}
}
// Skip to next node in listview display.
cur_entry = next_node(cur_entry);
}
UnlockPubScreenList();
// Remove any extra entries from list.
while(cur_entry) {
struct pubscreen_entry *next_entry;
// Set changed flag and detach from listview if needed.
if(list_changed == FALSE) {
GO_SetObjAttrs(go,PUBLIST_ID,0,GTLV_Labels,~0,TAG_END);
list_changed = TRUE;
}
// If this is the currently selected screen, stash its name.
if(cur_entry && gl->cur_pubscrn == cur_entry) {
strcpy(name_selected,gl->cur_pubscrn->name);
gl->cur_pubscrn = NULL;
}
next_entry = next_node(cur_entry);
Remove(&cur_entry->node);
AddHead(&gl->empty_list,&cur_entry->node);
cur_entry = next_entry;
}
if(name_selected[0] == 0 && list_changed) {
if(go->go_Screen) {
for(cur_entry = head_node(&gl->pubscrn_list);
cur_entry != NULL && cur_entry->screen != go->go_Screen;
cur_entry = next_node(cur_entry))
;
if(cur_entry != NULL) {
strcpy(name_selected,cur_entry->name);
}
} else {
GetDefaultPubScreen(name_selected);
}
}
if(list_changed) {
gl->cur_pubscrn = NULL;
for(cur_entry = head_node(&gl->pubscrn_list);
gl->cur_pubscrn == NULL && cur_entry != NULL;
cur_entry = next_node(cur_entry)) {
if(strcmp(name_selected,cur_entry->name) == 0)
gl->cur_pubscrn = cur_entry;
}
if(!gl->cur_pubscrn) gl->cur_pubscrn = head_node(&gl->pubscrn_list);
GO_SetObjAttrs(go,PUBLIST_ID,0,
GTLV_Labels, &gl->pubscrn_list,
GTLV_Selected, node_to_num(&gl->pubscrn_list,gl->cur_pubscrn),
TAG_END);
GO_SetObjAttrs(go,OWNER_ID,0,
GTTX_Text, gl->cur_pubscrn ? gl->cur_pubscrn->owner_name : "",
TAG_END);
}
// Check if default pub screen has changed
GetDefaultPubScreen(&name_selected[0]);
if(strcmp(name_selected,gl->defpub_name) != 0) {
strcpy(gl->defpub_name,name_selected);
list_changed = TRUE;
GO_SetObjAttrs(go,DEFAULT_ID,0,
GTTX_Text, gl->defpub_name,
TAG_END);
}
{
UWORD modes;
Forbid();
modes = SetPubScreenModes(0);
SetPubScreenModes(modes);
Permit();
update_checkbox(go,SHANGHAI_ID,modes&SHANGHAI);
update_checkbox(go,AUTOPOP_ID,modes&POPPUBSCREEN);
}
return list_changed;
}
static void remove_outline(struct GadOutline *go,struct GadOutline *dest_go)
{
struct main_globals *gl;
struct Node *cur_node;
if(!go) return;
gl = go->go_UserData;
if(gl) {
for(cur_node = head_node(&gl->outline_list);
cur_node != NULL;
cur_node = next_node(cur_node)) {
if((void *)cur_node->ln_Name == (void *)dest_go) {
Remove(cur_node);
FreeVec(cur_node);
cur_node = NULL;
}
}
}
if(dest_go) ((HANDLER *)dest_go->go_UserHandler)(dest_go,
HNDCMD_SHUTDOWN,(struct GOIMsg *)dest_go);
}
static void dist_hndcmd(struct GadOutline *go,ULONG cmd,void *msg)
{
struct main_globals *gl;
struct Node *curnode;
if(!go) return;
gl = go->go_UserData;
if(gl) {
// Send command to children.
for(curnode = head_node(&gl->outline_list);
curnode != NULL;
curnode = next_node(curnode)) {
struct GadOutline *cur_go;
cur_go = (struct GadOutline *)curnode->ln_Name;
if( ((HANDLER *)cur_go->go_UserHandler)(cur_go,cmd,msg)
== HNDRES_CLOSEWIN ) {
curnode = curnode->ln_Succ;
remove_outline(go,cur_go);
curnode = curnode->ln_Pred;
}
}
}
}
static void hide_windows(struct GadOutline *go)
{
dist_hndcmd(go,HNDCMD_HIDEWIN,NULL);
GO_CloseScreen(go); // Make sure we totally unlink.
}
static void move_windows(struct GadOutline *go)
{
dist_hndcmd(go,HNDCMD_MOVEWIN,go->go_Screen);
}
static void lock_program(struct GadOutline *go)
{
dist_hndcmd(go,HNDCMD_LOCK,NULL);
LockGadOutline(go);
}
static void unlock_program(struct GadOutline *go)
{
UnlockGadOutline(go);
dist_hndcmd(go,HNDCMD_UNLOCK,NULL);
}
static struct Node *add_outline(struct GadOutline *go,struct GadOutline *dest_go)
{
struct main_globals *gl;
struct Node *cur_node = NULL;
if(!go) return NULL;
if(!(gl = go->go_UserData)) return NULL;
if(gl) {
if(!(cur_node = AllocVec(sizeof(struct Node),MEMF_PUBLIC|MEMF_CLEAR))) {
return NULL;
}
cur_node->ln_Name = (UBYTE *)dest_go;
AddTail(&gl->outline_list,cur_node);
}
return cur_node;
}
static void update_curscrn(struct GadOutline *go)
{
struct main_globals *gl;
if(!go) return;
if( !(gl = go->go_UserData)) return;
GO_SetObjAttrs(go,OWNER_ID,0,
GTTX_Text, gl->cur_pubscrn
? gl->cur_pubscrn->owner_name : "",
TAG_END);
if(!gl->cur_pubscrn || (gl->cur_pubscrn->flags&PSNF_PRIVATE)) {
GO_SetObjGrpAttrs(go,GO_CMDID(CURSCRN_GID,0),0,
GA_Disabled,TRUE,TAG_END);
} else {
GO_SetObjGrpAttrs(go,GO_CMDID(CURSCRN_GID,0),0,
GA_Disabled,FALSE,TAG_END);
if(gl->cur_pubscrn->flags&PSNF_PRIVATE) {
GO_SetObjAttrs(go,JUMPTO_ID,0,GA_Disabled,TRUE,TAG_END);
} else {
GO_SetObjAttrs(go,JUMPTO_ID,0,GA_Disabled,FALSE,TAG_END);
}
if( gl->cur_pubscrn->visitor_count > 0
&& !(gl->cur_pubscrn->screen == go->go_Screen
&& gl->cur_pubscrn->visitor_count <= 2) ) {
GO_SetObjAttrs(go,CLOSE_ID,0,GA_Disabled,TRUE,TAG_END);
GO_SetObjAttrs(go,MODSCRN_ID,0,GA_Disabled,TRUE,TAG_END);
} else {
GO_SetObjAttrs(go,CLOSE_ID,0,GA_Disabled,FALSE,TAG_END);
GO_SetObjAttrs(go,MODSCRN_ID,0,GA_Disabled,FALSE,TAG_END);
}
}
}
static ULONG __saveds __interrupt
main_handler(struct GadOutline *go, ULONG command, struct GOIMsg *msg)
{
struct main_globals *gl;
struct Gadget *gadget;
ULONG class;
UWORD code;
UWORD qual;
if(go == NULL) return HNDRES_TERMINATE;
if( !(gl = (struct main_globals *)go->go_UserData) ) {
DestroyMain(go);
return HNDRES_TERMINATE;
}
if(command == HNDCMD_IDCMPMSG) {
if( msg ) {
class = msg->StdIMsg.Class;
code = msg->StdIMsg.Code;
qual = msg->StdIMsg.Qualifier;
gadget = (struct Gadget *)msg->StdIMsg.IAddress;
} else {
return HNDRES_TERMINATE;
}
} else if(command == HNDCMD_SHUTDOWN) {
if(msg && go != (struct GadOutline *)msg) {
remove_outline(go,(struct GadOutline *)msg);
update_curscrn(go);
return HNDRES_NORMAL;
} else {
return HNDRES_TERMINATE;
}
} else if(command == HNDCMD_TICK) {
dist_hndcmd(go,command,msg);
class = IDCMP_INTUITICKS;
} else {
return HNDRES_NORMAL;
}
switch (class) {
case IDCMP_CLOSEWINDOW:
{
return HNDRES_TERMINATE;
} break;
case IDCMP_REFRESHWINDOW:
{
GO_BeginRefresh(go);
GO_EndRefresh(go, TRUE);
} break;
case IDCMP_INTUITICKS:
{
if( (++gl->ticks_since_update) > 5) {
if(update_publist(go)) update_curscrn(go);
gl->ticks_since_update = 0;
}
} break;
case IDCMP_MENUPICK:
{
struct MenuItem *item;
while(code != MENUNULL) {
item = ItemAddress(go->go_MenuStrip, code);
switch((ULONG)GTMENUITEM_USERDATA(item)) {
case QUIT_ID:
{
return HNDRES_TERMINATE;
} break;
case ABOUT_ID:
{
lock_program(go);
GO_ShowError(go,GO_MAKEERR(GOTYPE_FINE,0),NULL,
"%ls v%ls\nCopyright © %ls Dianne Hackborn\nCreated on %ls at %ls\n\n"
"User interface created with\n^Zb v^Zv.^Zr\n\n"
"This program is shareware. If you find\n"
"it useful, please send $5 or whatever you\n"
"feel it is worth to:\n"
" Dianne Hackborn\n"
" 2895 Los Altos Drive\n"
" Meridian, ID 83642",
&__ProgName[0],&__FullVersion[0],&__BuildYear[0],&__BuildDate[0],&__BuildTime[0]);
unlock_program(go);
} break;
}
code = item->NextSelect;
}
} break;
case IDCMP_GADGETUP:
case IDCMP_GADGETDOWN:
{
switch(gadget->GadgetID) {
case PUBLIST_ID:
{
gl->cur_pubscrn = num_to_node(&gl->pubscrn_list,code);
update_curscrn(go);
} break;
case CLOSE_ID:
{
struct Screen *scrn;
if(gl->cur_pubscrn) {
BOOL do_reopen = FALSE;
scrn = LockPubScreen(gl->cur_pubscrn->name);
if(scrn == go->go_Screen) {
do_reopen = TRUE;
hide_windows(go);
GO_CloseScreen(go); // Make sure we totally unlink
}
Forbid();
UnlockPubScreen(NULL,scrn);
(void)CloseScrnTrack(scrn);
Permit();
if(do_reopen) {
GO_OpenWindow(go,
WA_PubScreenName, gl->cur_pubscrn->name,
TAG_END);
move_windows(go);
}
gl->cur_pubscrn = NULL;
}
if(update_publist(go)) update_curscrn(go);
} break;
case JUMPTO_ID:
{
hide_windows(go);
DimenGadOutline(go,
GOA_ScreenName,
gl->cur_pubscrn ? gl->cur_pubscrn->name : "",
GOA_ScreenFallBack, TRUE,
TAG_END);
if(go->go_LastReqReturn)
DimenGadOutline(go,GOA_ScreenAddr,NULL,TAG_END);
if(go->go_LastReqReturn)
DimenGadOutline(go,GOA_ScreenName,"Workbench",TAG_END);
if(go->go_LastReqReturn)
return HNDRES_TERMINATE;
move_windows(go);
if(!GO_OpenWindow(go,TAG_END)) return HNDRES_TERMINATE;
update_publist(go);
update_curscrn(go);
} break;
case EXAMINE_ID:
{
struct GadOutline *ex_go;
struct Screen *scrn;
if(!gl->cur_pubscrn)
return HNDRES_NORMAL;
if(!(scrn=LockPubScreen(gl->cur_pubscrn->name)))
return HNDRES_NORMAL;
if(ex_go=CreateExamine(go,gl->cur_pubscrn->name,scrn)) {
if(!add_outline(go,ex_go)) {
((HANDLER *)ex_go->go_UserHandler)(ex_go,
HNDCMD_SHUTDOWN,(struct GOIMsg *)ex_go);
}
}
UnlockPubScreen(NULL,scrn);
if(update_publist(go)) update_curscrn(go);
} break;
case MAKEDEF_ID:
{
if(gl->cur_pubscrn) {
SetDefaultPubScreen(gl->cur_pubscrn->name);
update_publist(go);
update_curscrn(go);
}
} break;
case DUPSCRN_ID:
{
struct GadOutline *ns_go;
struct Screen *scrn;
if(!gl->cur_pubscrn)
return HNDRES_NORMAL;
if(!(scrn=LockPubScreen(gl->cur_pubscrn->name)))
return HNDRES_NORMAL;
if(ns_go=CreateNewScrn(go,gl->cur_pubscrn->name,scrn,FALSE)) {
if(!add_outline(go,ns_go)) {
((HANDLER *)ns_go->go_UserHandler)(ns_go,
HNDCMD_SHUTDOWN,(struct GOIMsg *)ns_go);
}
}
UnlockPubScreen(NULL,scrn);
if(update_publist(go)) update_curscrn(go);
} break;
case MODSCRN_ID:
{
struct GadOutline *ns_go;
struct Screen *scrn;
if(!gl->cur_pubscrn)
return HNDRES_NORMAL;
if(!(scrn=LockPubScreen(gl->cur_pubscrn->name)))
return HNDRES_NORMAL;
if(ns_go=CreateNewScrn(go,gl->cur_pubscrn->name,scrn,TRUE)) {
if(!add_outline(go,ns_go)) {
((HANDLER *)ns_go->go_UserHandler)(ns_go,
HNDCMD_SHUTDOWN,(struct GOIMsg *)ns_go);
}
}
UnlockPubScreen(NULL,scrn);
if(update_publist(go)) update_curscrn(go);
} break;
case SHANGHAI_ID:
{
ULONG newval;
UWORD modes;
newval = GO_GetObjAttr(go,SHANGHAI_ID,0, GTCB_Checked,FALSE);
Forbid();
modes = SetPubScreenModes(0);
SetPubScreenModes(
(modes&~(SHANGHAI)) | (newval ? SHANGHAI : 0) );
Permit();
} break;
case AUTOPOP_ID:
{
ULONG newval;
UWORD modes;
newval = GO_GetObjAttr(go,AUTOPOP_ID,0, GTCB_Checked,FALSE);
Forbid();
modes = SetPubScreenModes(0);
SetPubScreenModes(
(modes&~(POPPUBSCREEN)) | (newval ? POPPUBSCREEN : 0) );
Permit();
} break;
case NEWSCRN_ID:
{
struct GadOutline *ns_go;
struct Screen *scrn;
if(!(scrn=LockPubScreen(NULL)))
return HNDRES_NORMAL;
if(ns_go=CreateNewScrn(go,NULL,scrn,FALSE)) {
if(!add_outline(go,ns_go)) {
((HANDLER *)ns_go->go_UserHandler)(ns_go,
HNDCMD_SHUTDOWN,(struct GOIMsg *)ns_go);
}
}
UnlockPubScreen(NULL,scrn);
if(update_publist(go)) update_curscrn(go);
} break;
case QUIT_ID:
{
return HNDRES_TERMINATE;
} break;
}
} break;
}
return HNDRES_NORMAL;
}
void DestroyMain(struct GadOutline *go)
{
struct main_globals *gl;
struct Node *curnode;
if(!go) return;
gl = go->go_UserData;
GO_SetObjAttrs(go,PUBLIST_ID,0,GTLV_Labels,0,TAG_END);
if(gl) {
// Close all opened outlines.
while( (curnode = RemTail(&gl->outline_list)) != NULL ) {
struct GadOutline *cur_go;
cur_go = (struct GadOutline *)curnode->ln_Name;
((HANDLER *)cur_go->go_UserHandler)(cur_go,
HNDCMD_SHUTDOWN,(struct GOIMsg *)cur_go);
FreeVec(curnode);
}
// Free list of public screens.
while( (curnode = RemTail(&gl->pubscrn_list)) != NULL ) {
FreeVec(curnode);
}
// Free extra list of public screen nodes.
while( (curnode = RemTail(&gl->empty_list)) != NULL ) {
FreeVec(curnode);
}
}
FreeGadOutline(go);
// Free global variables.
if(gl) FreeVec(gl);
}
struct GadOutline *CreateMain(struct MsgPort *glob_port)
{
struct GadOutline *go;
struct main_globals *gl;
go = AllocGadOutline(&main_outline[0],
GOA_OutlineSize, sizeof(main_outline),
//GOA_UserIDCMP, glob_port,
TAG_END);
if(!go) return NULL;
gl = AllocVec(sizeof(struct main_globals),MEMF_PUBLIC|MEMF_CLEAR);
if(!gl) {
DestroyMain(go);
return NULL;
}
NewList(&gl->pubscrn_list);
NewList(&gl->empty_list);
NewList(&gl->outline_list);
go->go_UserData = gl;
SetupBackFillHook(&gl->bf_hook,go);
GO_SetObjAttrs(go,WINTAGS_ID,0,WA_BackFill,&gl->bf_hook,TAG_END);
update_publist(go);
update_curscrn(go);
if( !GO_OpenWindow(go, WA_PubScreen, NULL, TAG_END) ) {
if( !GO_OpenWindow(go, WA_PubScreenName, "Workbench", TAG_END) ) {
DestroyMain(go);
return NULL;
}
}
return go;
}
static void pnum32(UBYTE *to,ULONG num,ULONG bitsperdig,ULONG numdig,ULONG space)
{
if(space == 0) space = 2000;
while(numdig > 0) {
UBYTE curdig;
curdig = (num>>((numdig-1)*bitsperdig)) & ((1<<bitsperdig)-1);
if(curdig < 10) *to = curdig + '0';
else *to = curdig + 'A' - 10;
to++;
numdig--;
if(numdig > 0 && (numdig%space) == 0) {
*to = '.';
to++;
}
}
*to = 0;
}
#define phex32(to,num,numdig,space) pnum32(to,num,4,numdig,space)
#define pbin32(to,num,numdig,space) pnum32(to,num,1,numdig,space)
static void read_modes(struct GadOutline *go,struct List *modelist)
{
ULONG mode;
NewList(modelist);
// Get display modes.
mode = INVALID_ID;
while( (mode = NextDisplayInfo(mode)) != INVALID_ID ) {
struct ModeEntry *entry;
struct NameInfo info;
if( ModeNotAvailable(mode) == 0
&& GetDisplayInfoData(NULL,(UBYTE *)&info,sizeof(info),
DTAG_NAME,mode) ) {
if(entry = GO_AllocMem(go,GOTYPE_WARN,
sizeof(struct ModeEntry),MEMF_PUBLIC|MEMF_CLEAR)) {
entry->mode = mode;
GetDisplayInfoData(NULL,(UBYTE *)&entry->disp,
sizeof(entry->disp),DTAG_DISP,mode);
GetDisplayInfoData(NULL,(UBYTE *)&entry->dims,
sizeof(entry->dims),DTAG_DIMS,mode);
GetDisplayInfoData(NULL,(UBYTE *)&entry->mntr,
sizeof(entry->mntr),DTAG_MNTR,mode);
entry->name = info;
if(entry->name.Name[0] == 0) {
entry->name.Name[0] = '0';
entry->name.Name[1] = 'x';
phex32(&entry->name.Name[2],mode,8,0);
}
entry->node.ln_Name = &entry->name.Name[0];
AddTail(modelist,&entry->node);
}
}
}
}
void delete_timer(struct timerequest *tr)
{
struct MsgPort *tp;
if (tr != 0 ) {
tp = tr->tr_node.io_Message.mn_ReplyPort;
if (tp != 0) {
DeletePort(tp);
}
CloseDevice( (struct IORequest *) tr );
DeleteExtIO( (struct IORequest *) tr );
}
}
struct timerequest *create_timer( ULONG unit )
{
LONG error;
struct MsgPort *timerport;
struct timerequest *TimerIO;
timerport = CreatePort( 0, 0 );
if (timerport == NULL )
return( NULL );
TimerIO = (struct timerequest *)
CreateExtIO( timerport, sizeof( struct timerequest ) );
if (TimerIO == NULL ) {
DeletePort(timerport); /* Delete message port */
return( NULL );
}
error = OpenDevice( TIMERNAME, unit,(struct IORequest *) TimerIO, 0L );
if (error != 0 ) {
delete_timer( TimerIO );
return( NULL );
}
return( TimerIO );
}
void abort_timer(struct timerequest *tr)
{
AbortIO((struct IORequest *)tr);
WaitIO((struct IORequest *)tr);
}
void send_timer(struct timerequest *tr)
{
tr->tr_time.tv_secs = 1;
tr->tr_time.tv_micro = 0;
tr->tr_node.io_Command = TR_ADDREQUEST;
SendIO((struct IORequest *)tr);
}
#ifdef BETALIB
struct Library *GadOutlineBase = NULL;
#endif
void __regargs main(int argc,char **argv)
{
struct Process *me = NULL;
struct Window *oldwin = NULL; // what me->pr_WindowPtr previously was
struct timerequest *timer;
struct GadOutline *main_go;
if( !(me = (struct Process *)FindTask(NULL)) ) {
exit(20);
}
oldwin = (struct Window *)me->pr_WindowPtr;
timer = create_timer(UNIT_VBLANK);
if(!timer) exit(20);
#ifdef BETALIB
if( !(GadOutlineBase = OpenLibrary("beta_gadoutline.library",1)) ) {
delete_timer(timer);
exit(20);
}
#endif
main_go = CreateMain(NULL);
if(!main_go) {
#ifdef BETALIB
CloseLibrary(GadOutlineBase);
#endif
delete_timer(timer);
exit(20);
}
read_modes(main_go,&ScreenModeList);
send_timer(timer); // Prime the pump... ;)
while(1) {
struct GadOutline *msg_go;
struct GOIMsg *msg;
ULONG ret = HNDRES_NORMAL;
me->pr_WindowPtr = (APTR)main_go->go_Window;
Wait( (1L<<main_go->go_MsgPort->mp_SigBit)
| (1L<<timer->tr_node.io_Message.mn_ReplyPort->mp_SigBit) );
while( (msg = GO_GetGOIMsg(main_go)) ) {
struct GOIMsg *dup_msg;
msg_go = GO_GetGOFromGOIMsg(msg);
if(msg_go)
dup_msg = GO_DupGOIMsg(msg_go,msg);
else
dup_msg = NULL;
GO_ReplyGOIMsg(msg);
if(dup_msg) {
ret = ((HANDLER *)msg_go->go_UserHandler)
(msg_go,HNDCMD_IDCMPMSG,dup_msg);
(void)GO_UndupGOIMsg(dup_msg);
}
if(ret == HNDRES_CLOSEWIN) {
ret = ((HANDLER *)main_go->go_UserHandler)
(main_go,HNDCMD_SHUTDOWN,(struct GOIMsg *)msg_go);
}
if(ret == HNDRES_TERMINATE) {
D(bug("Quiting..."));
DestroyMain(main_go);
#ifdef BETALIB
CloseLibrary(GadOutlineBase);
#endif
D(bug(" GadOutline..."));
abort_timer(timer);
D(bug(" Timer Request..."));
delete_timer(timer);
D(bug(" Timer Device. Done.\n"));
me->pr_WindowPtr = (APTR)oldwin;
exit(0);
}
}
if( GetMsg(timer->tr_node.io_Message.mn_ReplyPort) ) {
send_timer(timer);
((HANDLER *)main_go->go_UserHandler)(main_go,HNDCMD_TICK,NULL);
}
}
}